//
// Created by fengg on 2020/3/26.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
typedef struct {
    void *stack;
    int top;
    size_t item_size;
    int max_size;
} Stack ;

#define _ADDR(x) x->stack+x->item_size*x->top

int init(Stack *s,size_t item_size,size_t num){
    s->top = -1;
    s->stack =  malloc(item_size*num);
    s->item_size = item_size;
    s->max_size = num;
}

int isEmpty(Stack *s){
    return s->top < 0;
}

int isFill(Stack *s){
    return s->top >= s->max_size-1;
}

int push(Stack *s,const void *v,size_t t){
    if(!isFill(s)){
        ++s->top;
        memcpy(_ADDR(s),v,t);
        return 1;
    }
    return 0;
}

void* pop(Stack *s){
    if(!isEmpty(s)){
        void *p = _ADDR(s);
        --s->top;
        return p;
    }

    return NULL;
}

void* peak(Stack *s){
    if(!isEmpty(s)){

        return _ADDR(s);
    }
    return NULL;
}
enum op_code {
    plus = 0,
    min,
    times,
    divs,
    pow_
};
const char op_ack[]   = {'+','-','*','/','^' ,'(','\0'};
const int  op_level[] = { 0,  0,  1,  1,  2  , -1};





int op_cmp(char op1, char op2) {
    int c1,c2;
    for (c1 = 0;op1 != op_ack[c1] && op_ack[c1] != '\0'; ++c1);
    for (c2 = 0;op2 != op_ack[c2] && op_ack[c2] != '\0'; ++c2);
    return op_level[c1] - op_level[c2];
}
char raw_str[100] = {0x0};
char pro_str[100] = {0x0};
const char L_brackets = '(';
#define  SEPARATOR ','
#define _CHAR(x) *(char *)(x)
#define _INT(x) *(int *)(x)
int main(){
    Stack op_stack = {};
    Stack num_stack = {};
    int raw_str_len;
    int pro_str_index = -1;
    int digit_flag = 0,close_break = 0;
    int temp_int=0;
    int i,j;
    init(&op_stack,1,10);

    gets(raw_str);

    raw_str_len = strlen(raw_str);
    raw_str[--raw_str_len] = '\0';

    for (i = 0; i < raw_str_len; ++i) {
        if(isdigit(raw_str[i]) || isalpha(raw_str[i])){
            pro_str[++pro_str_index] = raw_str[i];
            digit_flag = 1;
        } else if ( raw_str[i] == '(' ){
            push(&op_stack,&L_brackets,1);
        } else if ( raw_str[i] == ')'){
            close_break = 1;
            if(digit_flag){
                digit_flag = 0;
                pro_str[++pro_str_index] = SEPARATOR;
            }
            while (!isEmpty(&op_stack) && _CHAR(peak(&op_stack)) != '('){
                pro_str[++pro_str_index] = _CHAR(pop(&op_stack));
                if(i < raw_str_len-1)
                    pro_str[++pro_str_index] = SEPARATOR;
            }
            pop(&op_stack);

        } else {
            if(digit_flag && !close_break){
                digit_flag = 0;
                pro_str[++pro_str_index] = SEPARATOR;
            } else if (digit_flag){
                digit_flag = 0;
                pro_str[++pro_str_index] = SEPARATOR;
            } else if (!digit_flag && !close_break){

                pro_str[++pro_str_index] = '0';
                if(i < raw_str_len-1)
                    pro_str[++pro_str_index] = SEPARATOR;
            }
            while (!isEmpty(&op_stack) && op_cmp(raw_str[i],_CHAR(peak(&op_stack))) <= 0 ){
                pro_str[++pro_str_index] = _CHAR(pop(&op_stack));
                if(i < raw_str_len-1)
                    pro_str[++pro_str_index] = SEPARATOR;
            }
            push(&op_stack,&raw_str[i],1);
        }
    }
    while (!isEmpty(&op_stack)){
        pro_str[++pro_str_index] = SEPARATOR;
        pro_str[++pro_str_index] = _CHAR((pop(&op_stack)));
    }

    printf("%s\n",pro_str);
    return 0;
    init(&num_stack,4,10);

    for (j = 0;pro_str[j] != 0; ++j) {
        if(isdigit(pro_str[j])){
            digit_flag = 1;
            temp_int = temp_int*10+pro_str[j]-'0';
        }
        else if (pro_str[j] == SEPARATOR){
            if (digit_flag)
                push(&num_stack,&temp_int,4),digit_flag = 0,temp_int = 0;
        } else{
            int o1,o2,o3;
            o1 = _INT(pop(&num_stack));
            o2 = _INT(pop(&num_stack));
            switch (pro_str[j]){
                case '+':
                    o3 = o1+o2;
                    break;
                case '-':
                    o3 = o2-o1;
                    break;
                case '*':
                    o3 = o1*o2;
                    break;
                case '/':
                    o3 = o2/o1;
                    break;
                case '^':
                    o3 = (int)pow((double)o2,(double)o1);
                    break;
            }
            push(&num_stack,&o3,4);
        }
    }


    printf("Eval:%d",_INT(pop(&num_stack)));
    return 0;
}


